<template>
  <!-- 地区概况组件  -->
  <div class="container">
    <div class="map">
      <!-- 地图容器 -->
      <div id="echart"></div>
      <!-- 数据容器 -->
      <div class="map-data">
        <!-- 城市时间展示 -->
        <h3>{{selectCityData.name}} {{todayTime}}</h3>
        <!-- 各项数据展示 -->
        <div class="city-data">
          <p
            v-for="(item, index) in selectCityData.data"
            :key="index"
          >{{item.branchName}}: &nbsp;{{item.count}}</p>
        </div>
        <!-- 详情跳转 -->
        <div v-if="[1001, 1002].includes($store.state.roleid)" class="details" @click="onGoDetails">详情&gt;</div>
      </div>
    </div>
  </div>
</template>

<script>
import echarts from "echarts";
import "echarts/map/js/china";
import { cityName, geoCoordMap, centerCity } from "./city";

// 地图绘制初始化数据
let option = {
  geo: {
    map: "", // 展示城市地图 可动态设置
    label: {
      // 区域名称显示
      show: true,
      textStyle: {
        color: "#FFF",
        fontWeight: 600,
        fontSize: 10
      }
    },
    zoom: 1.2, // 放大比例
    // roam: true, // 是否开启平游或缩放
    itemStyle: {
      // 区域间样式调节
      borderColor: "lightblue",
      areaColor: "rgb(10, 22, 63)"
    },
    emphasis: {
      // 区域高亮显示时状态
      label: {
        // 高亮时字体样式
        color: "#FFF",
        textStyle: {
          fontWeight: 600,
          fontSize: 14
        }
      },
      itemStyle: {
        // 高亮是区域样式
        areaColor: "rgb(42, 114, 246)",
        borderColor: "#ccc"
      }
    },
    regions: [] // 设置常亮城市
  },
  series: [
    // 当前城市
    {
      name: "currentCity",
      type: "effectScatter",
      coordinateSystem: "geo",
      symbolSize: 10, // 散点大小
      itemStyle: {
        normal: {
          color: "rgb(253, 253, 86)",
          shadowBlur: 6
        }
      },
      data: [] // 数据 可动态设置
    },
    // 省会城市
    {
      name: "centerCity",
      type: "scatter",
      coordinateSystem: "geo",
      symbol: "square",
      symbolSize: 12,
      itemStyle: {
        normal: {
          color: "rgba(235, 51, 35, 1)", // 标志颜色
          opacity: 1
        }
      },
      data: []
    }
  ]
};

export default {
  data() {
    return {
      mapJson: {}, // 地图Json数据
      selectCityData: {}, // 选择的数据
      myChart: null, // 全局定义
      dataList: [] // 数据
    };
  },
  props: {
    cityProvinceChartName: {
      type: String,
      default: ""
    },
    provinceChartAllData: {
      type: Array,
      default: () => []
    }
  },
  mounted() {
    // 加载地图Map数据
    this.loadMapData(this.$parent.currentProvinceShowId);
    // 设置echarts实例
    this.myChart = echarts.init(document.getElementById("echart"));
  },
  computed: {
    // 当前时间
    todayTime: function() {
      const time = new Date(),
        year = time.getFullYear(),
        month = time.getMonth() + 1,
        date = time.getDate();
      return `${year}.${month < 10 ? "0" + month : month}.${
        date < 10 ? "0" + date : date
      }`;
    }
  },
  methods: {
    // 加载地图Map数据
    loadMapData(areaCode) {
      AMapUI.loadUI(["geo/DistrictExplorer"], DistrictExplorer => {
        //创建一个实例
        var districtExplorer = new DistrictExplorer();
        // 注意: 类似北京要接口返回110000 带城区 才行 否则没数据
        districtExplorer.loadAreaNode(areaCode, (error, areaNode) => {
          if (error) {
            console.log(error);
            return;
          }
          this.mapJson = {};
          //特别注意这里 如果查看过正常的geojson文件 都会发现 文件都是以features 字段开头的 所以这里要记得加上
          this.mapJson.features = areaNode.getSubFeatures();
          this.loadRegisterMap(
            this.$parent.currentProvinceCityName,
            this.mapJson
          );
        });
      });
    },
    loadRegisterMap(mapName, data) {
      if (data) {
        echarts.registerMap(mapName, data);
        this.getData();
      }
    },
    // 获取疫情数据
    getData() {
      // 设置显示哪个省市地图 并按需引入地图数据
      option.geo.map = this.$parent.currentProvinceCityName;
      // 渲染数据
      this.renderData();
    },
    // 渲染数据
    renderData() {
      // 初始化默认城市数据
      // 如果父组件传值 获取该市的数据
      let cityPropsData = null;
      if (this.cityProvinceChartName) {
        const cityName = this.cityProvinceChartName
          .replace(/市|区｜新|省/g, "");
        cityPropsData = this.provinceChartAllData.filter(
          item => item.name.replace(/市|区｜新|省/g, "") == cityName
        )[0];
      }
      // 如果没有传值 默认使用 第一条数据展示
      this.setChartOption(
        this.cityProvinceChartName && cityPropsData
          ? {...cityPropsData, name: cityPropsData.name.replace(/新/g, "")}
          : this.provinceChartAllData[0]
      );
      // 监听点击事件
      this.myChart.on("click", params => {
        // 获取点击的城市
        const cityData = this.provinceChartAllData.filter(
          item => item.name.replace(/市|区｜新|省/g, "") == params.name.replace(/市|区｜新|省/g, "")
        )[0];
        cityData.name = cityData.name;
        // 设置数据
        cityData && this.setChartOption(cityData);
      });
    },
    // 设置数据 TODO: 可根据tab切换设置城市数据
    setChartOption(cityData) {
      // 设置展示数据
      this.selectCityData = cityData;
      // 设置点击目标城市
      const targetCity = this.mapJson.features.filter(
        item => item.properties.name.replace(/市|区｜新|省/g, "") == cityData.name.replace(/市|区｜新|省/g, "")
      )[0];
      // 获取选择城市位置
      const location =
        geoCoordMap[cityData.name] || targetCity.properties.centroid || targetCity.properties.center;
      option.series[0].data[0] = {
        name: cityData.name,
        value: location
      };
      // 设置选择城市常亮
      const cityNameJson = {
        '重庆': '重庆市',
        '北京': '北京市',
        '台湾': '台湾省',
        '上海': '上海市',
        '天津': '天津市'
      }
      option.geo.regions[0] = {
        name: cityNameJson[cityData.name] || cityData.name,
        selected: true
      };
      // 获取省会城市
      const currentCenterCity =
        centerCity[this.$parent.currentProvinceCityName];
      // 设置省会城市散点 如果是当前选中城市则隐藏
      if (currentCenterCity != cityData.name) {
        option.series[1].data[0] = {
          name: currentCenterCity,
          value: geoCoordMap[currentCenterCity]
        };
      } else {
        option.series[1].data[0] = {};
      }
      // 重绘数据
      this.myChart.setOption(option);
      // 地图经纬度转页面坐标 并 创建连线
      this.getOffsetCreateLint(location);
    },
    // 地图经纬度转页面坐标 并 创建连线
    getOffsetCreateLint(current) {
      // 获取系列
      const seriesModel = this.myChart
        .getModel()
        .getSeriesByIndex(option.series.length - 1);
      // 获取地理坐标系实例
      const coordSys = seriesModel.coordinateSystem;
      // 获取Offset坐标
      const point = coordSys.dataToPoint(current);

      // 获取echart节点
      const echartDom = document.querySelector("#echart");
      // 获取.map-data节点
      const mapDataDom = document.querySelector(".map-data");
      // 如果存在连线则删除
      if (echartDom.childNodes.length > 1) {
        echartDom.removeChild(echartDom.lastChild);
        echartDom.removeChild(echartDom.lastChild);
      }
      // 距离差 即为线的宽度
      const Length = 50;
      // 计算水平线的宽度
      const distance = echartDom.offsetWidth - point[0] - Length + 20;
      // 计算两线 垂直距离
      const pointLenght = point[1] - mapDataDom.offsetTop - 260;
      const verticalDimension = Math.abs(pointLenght);
      // 计算勾股定理 获取弯曲的线 实际的宽度
      const realityWidth = Math.sqrt(
        Math.pow(verticalDimension, 2) + Math.pow(Length, 2)
      );
      // 计算旋转角度
      const result = Math.round(
        Math.atan(verticalDimension / Length) / (Math.PI / 180)
      );

      // 创建连线 水平
      var lint1 = document.createElement("div");
      // 设置连线样式
      lint1.style = `width: ${distance}px;height: 2px;background: rgb(253, 253, 86);position: absolute;left: ${point[0] +
        Length}px;top: ${mapDataDom.offsetTop + 260}px;`;
      lint1.className = "lint1";
      // 追加连线
      echartDom.appendChild(lint1);

      // 创建连线 弯曲
      var lint2 = document.createElement("div");
      // 设置连线样式
      lint2.style = `width: ${
        pointLenght > 0 ? realityWidth : realityWidth + 1
      }px;height: 2px;background: rgb(253, 253, 86);position: absolute;left: ${
        point[0]
      }px;top: ${point[1]}px;transform: rotate(${
        pointLenght > 0 ? -result : result
      }deg);transform-origin: 0 0;border-radius: 8px;`;
      // 追加连线
      echartDom.appendChild(lint2);
    },
    // 跳转详情
    onGoDetails() {
      console.log(this.selectCityData); // 当前城市数据
    }
  },
  watch: {
    // 监听父组件传值
    cityProvinceChartName: {
      handler() {
        this.getData();
      }
    },
    provinceChartAllData: {
      handler() {
        this.getData();
      },
      deep:true
    },
  }
};
</script>

<style lang="less" scoped>
.container {
  min-width: 900px;
  background: rgb(1, 4, 23);

  .map {
    position: relative;
    display: flex;
    justify-content: center;
    padding: 30px;

    // 地图样式
    #echart {
      position: relative;
      height: 640px;
      width: 860px;
      margin-right: 20px;

      /deep/ .lint1 {
        &::before {
          position: absolute;
          left: -1px;
          display: inline-block;
          content: "";
          width: 2px;
          height: 2px;
          border-radius: 100%;
          background: rgb(253, 253, 86);
        }
      }
    }

    // 数据展示样式
    .map-data {
      position: relative;
      z-index: 1000;
      background: rgb(10, 21, 64);
      height: 470px;
      width: 300px;
      min-width: 200px;
      border-radius: 4px;
      margin-top: 80px;
      padding: 0 20px;
      color: #fff;
      line-height: 26px;
      h3 {
        padding: 30px 0 16px;
      }
      .city-data {
        p {
          display: flex;
          align-items: center;
          font-weight: 600;
          font-size: 16px;
          line-height: 42px;

          &::before {
            display: inline-block;
            content: "";
            width: 8px;
            height: 8px;
            border-radius: 8px;
            margin-right: 8px;
          }

          &:nth-child(1)::before {
            background: rgb(95, 199, 250);
          }

          &:nth-child(2)::before {
            background: rgb(230, 135, 60);
          }

          &:nth-child(3)::before {
            background: rgb(200, 87, 75);
          }

          &:nth-child(4)::before {
            background: rgb(170, 35, 59);
          }

          &:nth-child(5)::before {
            background: rgb(235, 168, 121);
          }

          &:nth-child(6)::before {
            background: rgb(88, 191, 125);
          }

          &:nth-child(7)::before {
            background: rgb(200, 87, 75);
          }
          &:nth-child(8)::before {
            background: rgb(230, 135, 60);
          }
          &:nth-child(9)::before {
            background: rgb(95, 199, 250);
          }
        }
      }

      .details {
        position: absolute;
        bottom: 20px;
        right: 20px;
        font-size: 14px;
        text-align: right;
        cursor: pointer;
        color: #4353da;
        text-align: right;
      }
    }
  }
}
</style>
